// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
// Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
// ------------------------------------------------------------

#pragma once

namespace Reliability
{
    namespace ReconfigurationAgentComponent
    {
        namespace Communication
        {
            // Buffers and sends messages to the FM
            // Messages are generated by calling FailoverUnit::TryComposeFMMessage
            class FMMessageBuilder
            {
                DENY_COPY(FMMessageBuilder);

            public:
                FMMessageBuilder(
                    FMTransport & transport,
                    Reliability::FailoverManagerId const & target);

                void TakeEntriesInReplicaUpMessage(
                    __out Infrastructure::EntityEntryBaseSet & entries) ;

                void Send(
                    std::wstring const & activityId,
                    FMMessageDescription & description);

                void Finalize(
                    std::wstring const & activityId,
                    bool isLast);

            private:
                void AddReplicaUp(
                    Infrastructure::EntityEntryBaseSPtr const & entry,
                    FMMessageData::ReplicaUpElement && item);

                void SendReplicaUp(
                    std::wstring const & activityId,
                    bool isLast);

                void SendReplicaMessage(
                    std::wstring const & activityId,
                    Infrastructure::EntityEntryBaseSPtr const & entry,
                    RSMessage const & message,
                    ReplicaMessageBody const & body);

                std::vector<Reliability::FailoverUnitInfo> replicaUpNormalList_;
                std::vector<Reliability::FailoverUnitInfo> replicaUpDroppedList_;
                Infrastructure::EntityEntryBaseSet replicaUpMessageEntities_;

                std::map<Reliability::FailoverUnitId, Reliability::ReplicaDescription> replicaDownList_;

                FMTransport & transport_;
                FailoverManagerId const target_;
            };
        }
    }
}
